home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / c / qtools0.2-src.lha / src / libqtools / bsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  46.4 KB  |  1,291 lines

  1. #define    LIBQTOOLS_CORE
  2. #define    LIBQBUILD_CORE
  3. #include "../include/libqtools.h"
  4. #include "../include/libqbuild.h"
  5. #include "../include/libqdisplay.h"
  6.  
  7. bool newBsp = FALSE, newLit = FALSE, newVis = FALSE;
  8.  
  9. /* light */
  10. bool waterlit = FALSE, extra = FALSE, doradiosity = FALSE;
  11. float scale = 0, range = 0;
  12.  
  13. /* qbsp */
  14. bool watervis = FALSE, slimevis = FALSE;
  15. bool nofill = FALSE, notjunc = FALSE, noclip = FALSE, onlyents = FALSE, usehulls = FALSE;
  16. int subdivide = 0, hullnum = 0;
  17.  
  18. /* vis */
  19. bool fastvis = FALSE;
  20. int vislevel = 2;
  21.  
  22. /*
  23.  * =============
  24.  * AddBSP
  25.  *
  26.  * this function manages updating and/or creating and/or replacing of bsp-files
  27.  * it is possible to replace the light and visibility lumps rather than calc-
  28.  * ulating them new. it is a high level function to call the mid-level functions
  29.  * light, vis and qbsp
  30.  * TODO: the function should be capable to replace textures, the reason why that
  31.  * isn't done is the missing CutOff and PasteIn functions
  32.  * =============
  33.  */
  34. bool AddBSP(struct palpic *inPic, struct rawdata *inData, char *bspName, operation procOper, filetype inType)
  35. {
  36.   bool retval = FALSE;
  37.   bool appendPic = FALSE;
  38.   char *procName = 0;
  39.   char *srcName;
  40.   HANDLE bspFile = 0;
  41.  
  42.   __memBase = 0;
  43.  
  44. #ifdef    MEM_SIZETRACK
  45.   mprintf(" memory  :        %7i (       %7i)\n", memcounter, mempeak);
  46. # ifdef    MEM_ANALYSE
  47.   mprintf("                  %7i (       %7i)\n", memallocs, mempeakallocs);
  48.   mprintf("                  %7i (       %7i)\n", memcounter / memallocs, mempeak / mempeakallocs);
  49. # endif
  50. #endif
  51.  
  52.   if (inPic) {
  53.     procName = inPic->name;
  54.     appendPic = TRUE;
  55.   }
  56.   else if (inData) {
  57.     procName = inData->name;
  58.     appendPic = FALSE;
  59.   }
  60.   srcName = GetExt(procName);
  61.  
  62.   if (!__strcmp(srcName, "wad") || (inType == TYPE_WAD2))
  63.     appendPic = TRUE;
  64.  
  65.   if (appendPic) {
  66.   }
  67.   else {
  68.     bool oldBsp = FALSE, oldLit = FALSE, oldVis = FALSE;
  69.  
  70.     if (!__strcmp(srcName, "bsp") || (inType == TYPE_BSP)) {
  71.       oldBsp = TRUE;
  72.       newBsp = FALSE;
  73.       inType = TYPE_BSP;
  74.     }
  75.     else if (!__strcmp(srcName, "map") || (inType == TYPE_MAP)) {
  76.       newBsp = TRUE;
  77.       oldBsp = FALSE;
  78.       inType = TYPE_MAP;
  79.     }
  80.     else if (!__strcmp(srcName, "iob") || (inType == TYPE_IMAGINE)) {
  81.       newBsp = TRUE;
  82.       oldBsp = FALSE;
  83.       inType = TYPE_IMAGINE;
  84.     }
  85.     else if (!__strcmp(srcName, "prt") || (inType == TYPE_PRT)) {
  86.       newVis = TRUE;
  87.       oldVis = FALSE;
  88.       inType = TYPE_PRT;
  89.     }
  90.     else if (!__strcmp(srcName, "vis") || (inType == TYPE_VIS)) {
  91.       oldVis = oldBsp = TRUE;
  92.       newVis = newBsp = FALSE;
  93.       inType = TYPE_VIS;
  94.     }
  95.     else if (!__strcmp(srcName, "lit") || (inType == TYPE_LIT)) {
  96.       oldLit = oldBsp = TRUE;
  97.       newLit = newBsp = FALSE;
  98.       inType = TYPE_LIT;
  99.     }
  100.  
  101.     while (1) {
  102.       if (!setjmp(eabort)) {
  103.     if (oldBsp) {
  104.       if ((bspFile = __open(bspName, H_READWRITE_BINARY_OLD)) < 0) {
  105.         eprintf(failed_fileopen, bspName);
  106.         break;
  107.       }
  108.       if (!(bspMem = LoadBSP(bspFile, ALL_QUAKE1_LUMPS, BSP_VERSION_Q1))) {
  109.         eprintf(failed_fileload, bspName);
  110.         break;
  111.       }
  112.  
  113.       /*bspMem->bspOptions |= QBSP_NOTEXTURES; */
  114.  
  115.       __close(bspFile);
  116.       if ((bspFile = __open(bspName, H_WRITE_BINARY)) < 0) {
  117.         eprintf(failed_fileopen, bspName);
  118.         break;
  119.       }
  120.     }
  121.     else {
  122.       if ((bspFile = __open(bspName, H_WRITE_BINARY)) < 0) {
  123.         eprintf(failed_fileopen, bspName);
  124.         break;
  125.       }
  126.       if (!(bspMem = (struct memory *)tmalloc(sizeof(struct memory)))) {
  127.         eprintf(failed_memory, sizeof(struct memory), "bspMem");
  128.         break;
  129.       }
  130.  
  131.       /* init the tables to be shared by all models */
  132.       BeginBSPFile(bspMem);
  133.  
  134.       bspMem->mapOptions |= (newLit ? MAP_LOADLIGHTS : 0);
  135.  
  136.       bspMem->bspOptions |= (watervis ? QBSP_WATERVIS : 0);
  137.       bspMem->bspOptions |= (slimevis ? QBSP_SLIMEVIS : 0);
  138.       bspMem->bspOptions |= (nofill ? QBSP_NOFILL : 0);
  139.       bspMem->bspOptions |= (notjunc ? QBSP_NOTJUNC : 0);
  140.       bspMem->bspOptions |= (noclip ? QBSP_NOCLIP : 0);
  141.       bspMem->bspOptions |= (onlyents ? QBSP_ONLYENTS : 0);
  142.       bspMem->bspOptions |= (usehulls ? QBSP_USEHULLS : 0);
  143.  
  144.       /* load brushes and bspMem->mapentities */
  145.       if (inType == TYPE_IMAGINE) {
  146.         if ((retval = LoadTDDDFile(bspMem, inData->rawdata)) == FALSE) {
  147.           eprintf(failed_fileload, "TDDD");
  148.           break;
  149.         }
  150.       }
  151.       else if (inType == TYPE_MAP) {
  152.         if ((retval = LoadMapFile(bspMem, (char *)inData->rawdata)) == FALSE) {
  153.           eprintf(failed_fileload, "map");
  154.           break;
  155.         }
  156.       }
  157.  
  158.       mprintf(oper_create, "bsp-data", bspName);
  159.       if ((retval = qbsp(bspMem, hullnum, subdivide, bspName)) == FALSE) {
  160.         eprintf("failed to calculate bsp-tree\n");
  161.         break;
  162.       }
  163.     }
  164.  
  165.     bspMem->visOptions |= (fastvis ? VIS_FAST : 0);
  166.     bspMem->visOptions |= (verbose ? VIS_VERBOSE : 0);
  167.  
  168.     if (newVis) {
  169.       mprintf(oper_create, "vis-data", bspName);
  170.       if ((retval = vis(bspMem, vislevel, (char *)inData->rawdata)) == FALSE) {
  171.         eprintf("failed to calculate vis-data\n");
  172.         break;
  173.       }
  174.     }
  175.     else if (oldVis) {
  176.       mprintf(oper_replace, "vis-data", bspName);
  177.       FreeClusters(bspMem, LUMP_VISIBILITY);
  178.       bspMem->shared.quake1.dvisdata = inData->rawdata;
  179.       bspMem->shared.quake1.visdatasize = inData->size;
  180.       /*WriteBSP(bspFile, bspMem, BSP_VERSION_Q1); */
  181.       retval = TRUE;
  182.       break;
  183.     }
  184.  
  185.     bspMem->litOptions |= (newLit ? LIGHT_MEM : 0);
  186.     bspMem->litOptions |= (radiosity ? LIGHT_RADIOSITY : 0);
  187.     bspMem->litOptions |= (extra ? LIGHT_EXTRA : 0);
  188.     bspMem->litOptions |= (waterlit ? LIGHT_WATERLIT : 0);
  189.  
  190.     if (newLit) {
  191.       mprintf(oper_create, "light-data", bspName);
  192.       if ((retval = light(bspMem, scale, range)) == FALSE) {
  193.         eprintf("failed to calculate lit-data\n");
  194.         break;
  195.       }
  196.     }
  197.     else if (oldLit) {
  198.       mprintf(oper_replace, "light-data", bspName);
  199.       FreeClusters(bspMem, LUMP_LIGHTING);
  200.       bspMem->shared.quake1.dlightdata = inData->rawdata;
  201.       bspMem->shared.quake1.lightdatasize = inData->size;
  202.       /*WriteBSP(bspFile, bspMem, BSP_VERSION_Q1); */
  203.       retval = TRUE;
  204.       break;
  205.     }
  206.  
  207.     FinishBSPFile(bspMem, bspFile);
  208.     retval = TRUE;
  209.       }
  210.       break;
  211.     }
  212.   }
  213.   if (bspFile)
  214.     __close(bspFile);
  215.   if (bspMem) {
  216.     FreeClusters(bspMem, 0);
  217.     tfree(bspMem);
  218.   }
  219.  
  220. #ifdef    MEM_SIZETRACK
  221.   mprintf(" memory  :        %7i (       %7i)\n", memcounter, mempeak);
  222. #ifdef    MEM_ANALYSE
  223.   mprintf("                  %7i (       %7i)\n", memallocs, mempeakallocs);
  224.   mprintf("                  %7i (       %7i)\n", memcounter / memallocs, mempeak / mempeakallocs);
  225. #endif
  226. #endif
  227.   return retval;
  228. }
  229.  
  230. /*
  231.  * =============
  232.  * ExtractBSP
  233.  *
  234.  * this is the exact opposite of the addbsp-function
  235.  * TODO: scripting for bsp-files
  236.  * =============
  237.  */
  238. bool ExtractBSP(HANDLE bspFile, FILE * script, char *destDir, char *entryName, filetype outType, operation procOper, bool recurse)
  239. {
  240.   HANDLE outFile;
  241.   bool retval = FALSE;
  242.  
  243.   __memBase = 0;
  244.  
  245. #ifdef    PRINTCALLS
  246.   mprintf("ExtractBSP(%lx, %lx, %s, %s, %d, %d, %d)\n", bspFile, script, destDir, entryName, outType, procOper, recurse);
  247. #endif
  248.  
  249.   if (!setjmp(eabort)) {
  250.     int i;
  251.     char destPath[NAMELEN_PATH], *destName;
  252.     bool toWad = FALSE, toMap = FALSE, toVis = FALSE, toLit = FALSE, toIob = FALSE, toBsp = FALSE, toTex = TRUE;
  253.     int bspMask;
  254.  
  255.     __strncpy(destPath, destDir, NAMELEN_PATH - 1);
  256.     if (!entryName) {
  257.       destName = smalloc(destDir);
  258.       destName[__strlen(destName) - 1] = '\0';
  259.            if (outType == TYPE_WAD2) {        toWad = TRUE;                bspMask = LUMP_TEXTURES;    }
  260.       else if (outType == TYPE_MAP) {        toMap = TRUE;        toTex = FALSE;    bspMask = BSP_QUAKE1_LUMPS;    }
  261.       else if (outType == TYPE_IMAGINE) {    toMap = toIob = TRUE;    toTex = FALSE;    bspMask = BSP_QUAKE1_LUMPS;    }
  262.       else if (outType == TYPE_VIS) {        toVis = TRUE;        toTex = FALSE;    bspMask = LUMP_VISIBILITY;    }
  263.       else if (outType == TYPE_LIT) {        toLit = TRUE;        toTex = FALSE;    bspMask = LUMP_LIGHTING;    }
  264.       else if (outType == TYPE_BSP) {        toBsp = TRUE;        toTex = FALSE;    bspMask = ALL_QUAKE1_LUMPS;    }
  265.       else {                    toWad = toMap = toVis = toLit = TRUE;    bspMask = ALL_QUAKE1_LUMPS;    }                                /* default: extract all */
  266.       __strncat(destPath, GetFile(destName), NAMELEN_PATH - 1);
  267.       tfree(destName);
  268.     }
  269.     else {
  270.       destName = GetExt(entryName);
  271.       __strncat(destPath, GetFile(entryName), NAMELEN_PATH - 1);
  272.       if (!__strcmp(destName, "wad") || (outType == TYPE_WAD2)) {
  273.     entryName = 0;    toWad = TRUE;        bspMask = LUMP_TEXTURES;
  274.       }
  275.       else if (!__strcmp(destName, "map") || (outType == TYPE_MAP)) {
  276.     toTex = FALSE;    toMap = TRUE;        bspMask = BSP_QUAKE1_LUMPS;
  277.       }
  278.       else if (!__strcmp(destName, "iob") || (outType == TYPE_IMAGINE)) {
  279.     toTex = FALSE;    toMap = toIob = TRUE;    bspMask = BSP_QUAKE1_LUMPS;
  280.       }
  281.       else if (!__strcmp(destName, "vis") || (outType == TYPE_VIS)) {
  282.     toTex = FALSE;    toVis = TRUE;        bspMask = LUMP_VISIBILITY;
  283.       }
  284.       else if (!__strcmp(destName, "lit") || (outType == TYPE_LIT)) {
  285.     toTex = FALSE;    toLit = TRUE;        bspMask = LUMP_LIGHTING;
  286.       }
  287.       else if (!__strcmp(destName, "bsp") || (outType == TYPE_BSP)) {
  288.     toTex = FALSE;    toBsp = TRUE;        bspMask = ALL_QUAKE1_LUMPS;
  289.       }
  290.       else
  291.     bspMask = LUMP_TEXTURES;
  292.     }
  293.  
  294.     if ((bspMem = LoadBSP(bspFile, bspMask, BSP_VERSION_Q1))) {
  295.       if (procOper == OP_EXTRACT)
  296.     CreatePath(destPath);
  297.  
  298.       if ((bspMem->shared.quake1.dtexdata) && (toTex)) {
  299.     int *MipOffsets = (int *)bspMem->shared.quake1.dtexdata;
  300.     int MipNums = *MipOffsets++;
  301.  
  302.     /*
  303.      * decode mips from bsp
  304.      */
  305.     ReplaceExt(destPath, "wad");
  306.     for (i = 0; i < MipNums; i++) {
  307.       struct mipmap *Texture = (struct mipmap *)(MipOffsets[i] + bspMem->shared.quake1.dtexdata);
  308.  
  309.       if ((Texture != (struct mipmap *)-1) && !(entryName && fnmatch(entryName, Texture->name, FNM_PATHNAME))) {
  310.         char fileName[NAMELEN_PATH];
  311.  
  312.         __strncpy(fileName, destDir, NAMELEN_PATH - 1);
  313.         __strncat(fileName, Texture->name, NAMELEN_PATH - 1);
  314.         AppendType(fileName, outType, ".mip");
  315.  
  316.         switch (procOper) {
  317.           case OP_EXTRACT:{
  318.           struct palpic *MipMap;
  319.  
  320.           if ((MipMap = ParseMipMap(Texture, MIPMAP_0))) {
  321.             if (toWad) {
  322.               mprintf(oper_extract, MipMap->name, destPath);
  323.               AddWAD2(MipMap, 0, destPath, OP_UPDATE, WAD2_MIPMAP);
  324.             }
  325.             else {
  326.               FILE *fileDst;
  327.  
  328.               mprintf(oper_extract, MipMap->name, fileName);
  329.               CreatePath(fileName);
  330.  
  331.               if ((fileDst = __fopen(fileName, F_WRITE_BINARY))) {
  332.             if (outType != TYPE_NONE)
  333.               retval = PutImage(fileDst, MipMap, outType);
  334.             else
  335.               retval = PutMipMap(fileno(fileDst), MipMap);
  336.             __fclose(fileDst);
  337.               }
  338.               else
  339.             eprintf(failed_fileopen, fileName);
  340.             }
  341.             pfree(MipMap);
  342.           }
  343.           else
  344.             eprintf(failed_fileread, MipMap->name);
  345.         }
  346.         break;
  347.           case OP_DELETE:{
  348.           int len, diff;
  349.  
  350.           len = MIP_MULT(LittleLong(Texture->width) * LittleLong(Texture->height)) + sizeof(struct mipmap);
  351.           diff = bspMem->shared.quake1.texdatasize - (int)((long int)Texture - (long int)&MipOffsets[MipNums]);
  352.           __memcpy(Texture, ((unsigned char *)Texture) + len, len);
  353.  
  354.           for (diff = 0; diff < MipNums; diff++)
  355.             /* subtract cutoff-region from the offsets if they lie behind it */
  356.             if (MipOffsets[diff] > MipOffsets[i])
  357.               MipOffsets[diff] -= len;
  358.  
  359.           MipOffsets[i] = -1;
  360.           bspMem->shared.quake1.texdatasize -= len;
  361.         }
  362.         break;
  363.           case OP_VIEW:{
  364.           struct palpic *MipMap;
  365.  
  366.           mprintf(oper_view, Texture->name, fileName);
  367.           if ((MipMap = ParseMipMap(Texture, MIPMAP_0))) {
  368.             if (DisplayPicture(MipMap->rawdata, MipMap->name, MipMap->width, MipMap->height, 8, TRUE))
  369.               i = MipNums;
  370.             pfree(MipMap);
  371.             retval = TRUE;
  372.           }
  373.         }
  374.         break;
  375.           case OP_LIST:
  376.           case OP_DEFAULT:
  377.           default:{
  378.           mprintf("%16s (offset: %8d) %4dx%d\n", Texture->name, MipOffsets[i], LittleLong(Texture->width), LittleLong(Texture->height));
  379.           retval = TRUE;
  380.         }
  381.         break;
  382.         }
  383.         if (script)
  384.           fprintf(script, "update %s as %s as %c\n", fileName, Texture->name, WAD2_MIPMAP);
  385.       }
  386.     }
  387.     if ((toWad) && (recurse))
  388.       retval = processName(destPath, 0, 0, outType, 0, 0, procOper, script ? TRUE : FALSE, recurse);
  389.       }
  390.  
  391.       if ((bspMem->shared.quake1.dentdata) && (toMap)) {
  392.     /*
  393.      * decode map from bsp
  394.      */
  395.     if (procOper == OP_EXTRACT) {
  396.       FILE *mapFile;
  397.  
  398.       LoadMapFile(bspMem, bspMem->shared.quake1.dentdata);
  399.       if (toWad)
  400.         SetKeyValue(FindEntityWithModel(bspMem, 0), "wad", destPath);
  401.  
  402.       ReplaceExt(destPath, toIob ? "iob" : "map");
  403.       mprintf(oper_extract, "bsp-data", destPath);
  404.  
  405.       if ((mapFile = __fopen(destPath, toIob ? F_WRITE_BINARY : "w"))) {
  406.         LoadBSPFile(bspMem);
  407.  
  408.         if (toIob)
  409.           SaveTDDDFile(bspMem, fileno(mapFile));
  410.         else
  411.           SaveMapFile(bspMem, mapFile);
  412.  
  413.         __fclose(mapFile);
  414.         retval = TRUE;
  415.       }
  416.     }
  417.     else if (procOper == OP_VIEW)
  418.       retval = DisplayBSP(bspMem, "bspFile ...", 320, 200, 8, DISPLAY_FLAT, FALSE);
  419.       }
  420.  
  421.       if ((bspMem->shared.quake1.dvisdata) && (toVis)) {
  422.     /*
  423.      * decode vis from bsp
  424.      */
  425.     if (procOper == OP_EXTRACT) {
  426.       ReplaceExt(destPath, "vis");
  427.       mprintf(oper_extract, "vis-data", destPath);
  428.  
  429.       if ((outFile = __open(destPath, H_WRITE_BINARY)) > 0) {
  430.         __write(outFile, (void *)bspMem->shared.quake1.dvisdata, bspMem->shared.quake1.visdatasize * sizeof(unsigned char));
  431.         __close(outFile);
  432.         retval = TRUE;
  433.       }
  434.     }
  435.     else if ((procOper == OP_VIEW) && (!toMap))        /* display only if not displayed previous */
  436.       retval = DisplayBSP(bspMem, "bspFile ...", 320, 200, 8, DISPLAY_FLAT, FALSE);
  437.     else if (procOper == OP_DELETE)
  438.       FreeClusters(bspMem, LUMP_VISIBILITY);
  439.       }
  440.  
  441.       if ((bspMem->shared.quake1.dlightdata) && (toLit)) {
  442.     /*
  443.      * decode lit from bsp
  444.      */
  445.     if (procOper == OP_EXTRACT) {
  446.       ReplaceExt(destPath, "lit");
  447.       mprintf(oper_extract, "light-data", destPath);
  448.  
  449.       if ((outFile = __open(destPath, H_WRITE_BINARY)) > 0) {
  450.         __write(outFile, (void *)bspMem->shared.quake1.dlightdata, bspMem->shared.quake1.lightdatasize * sizeof(unsigned char));
  451.         __close(outFile);
  452.         retval = TRUE;
  453.       }
  454.     }
  455.     else if ((procOper == OP_VIEW) && (!toMap) && (!toVis))    /* display only if not displayed previous */
  456.       retval = DisplayBSP(bspMem, "bspFile ...", 320, 200, 8, DISPLAY_FLAT, FALSE);
  457.     else if (procOper == OP_DELETE)
  458.       FreeClusters(bspMem, LUMP_LIGHTING);
  459.       }
  460.  
  461.       if ((toBsp) && (procOper == OP_EXTRACT)) {
  462.     /*
  463.      * decode bsp from bsp
  464.      * mostly for conversions between the bsp-file versions
  465.      */
  466.     ReplaceExt(destPath, "bsp");
  467.     mprintf(oper_extract, "bsp-data", destPath);
  468.  
  469.     if ((outFile = __open(destPath, H_WRITE_BINARY)) > 0) {
  470.       WriteBSP(outFile, bspMem, BSP_VERSION_Q1);
  471.       __close(outFile);
  472.       retval = TRUE;
  473.     }
  474.       }
  475.  
  476.       if ((procOper == OP_LIST) || (procOper == OP_DEFAULT))
  477.     PrintClusters(bspMem, 0, FALSE);
  478.       else if(procOper == OP_DELETE)
  479.         WriteBSP(bspFile, bspMem, BSP_VERSION_Q1);
  480.    /* else if(procOper == OP_VIEW)
  481.         DisplayEnd(); */
  482.  
  483.       FreeClusters(bspMem, 0);
  484.     }
  485.     else
  486.       eprintf(failed_fileload, "bspFile");
  487.   }
  488.   return retval;
  489. }
  490.  
  491. /*
  492.  * =============
  493.  * SwapBSPFile
  494.  * 
  495.  * Byte swaps all data in a bsp file.
  496.  * =============
  497.  */
  498. static void SwapBSPFile(__memBase, bool toDisk)
  499. {
  500.   int i, c;
  501.   short int j = 0;
  502.  
  503.   oprintf("swapmask: %lx\n", bspMem->availHeaders);
  504.  
  505.   /* same in both */
  506.   /*
  507.    * planes
  508.    */
  509.   if (bspMem->availHeaders & LUMP_PLANES)
  510.     for (i = 0; i < bspMem->shared.quake1.numplanes; i++) {
  511.       for (j = 0; j < 3; j++)
  512.     bspMem->shared.quake1.dplanes[i].normal[j] = LittleFloat(bspMem->shared.quake1.dplanes[i].normal[j]);
  513.       bspMem->shared.quake1.dplanes[i].dist = LittleFloat(bspMem->shared.quake1.dplanes[i].dist);
  514.       bspMem->shared.quake1.dplanes[i].type = LittleLong(bspMem->shared.quake1.dplanes[i].type);
  515.     }
  516.  
  517.   /*
  518.    * vertexes
  519.    */
  520.   if (bspMem->availHeaders & LUMP_VERTEXES)
  521.     for (i = 0; i < bspMem->shared.quake1.numvertexes; i++) {
  522.       for (j = 0; j < 3; j++)
  523.     bspMem->shared.quake1.dvertexes[i].point[j] = LittleFloat(bspMem->shared.quake1.dvertexes[i].point[j]);
  524.     }
  525.  
  526.   /*
  527.    * faces
  528.    */
  529.   if (bspMem->availHeaders & LUMP_FACES)
  530.     for (i = 0; i < bspMem->shared.quake1.numfaces; i++) {
  531.       bspMem->shared.quake1.dfaces[i].texinfo = LittleShort(bspMem->shared.quake1.dfaces[i].texinfo);
  532.       bspMem->shared.quake1.dfaces[i].planenum = LittleShort(bspMem->shared.quake1.dfaces[i].planenum);
  533.       bspMem->shared.quake1.dfaces[i].side = LittleShort(bspMem->shared.quake1.dfaces[i].side);
  534.       bspMem->shared.quake1.dfaces[i].lightofs = LittleLong(bspMem->shared.quake1.dfaces[i].lightofs);
  535.       bspMem->shared.quake1.dfaces[i].firstedge = LittleLong(bspMem->shared.quake1.dfaces[i].firstedge);
  536.       bspMem->shared.quake1.dfaces[i].numedges = LittleShort(bspMem->shared.quake1.dfaces[i].numedges);
  537.     }
  538.  
  539.   /*
  540.    * marksurfaces
  541.    */
  542.   if (bspMem->availHeaders & LUMP_MARKSURFACES)
  543.     for (i = 0; i < bspMem->shared.quake1.nummarksurfaces; i++)
  544.       bspMem->shared.quake1.dmarksurfaces[i] = LittleShort(bspMem->shared.quake1.dmarksurfaces[i]);
  545.  
  546.   /*
  547.    * edges
  548.    */
  549.   if (bspMem->availHeaders & LUMP_EDGES)
  550.     for (i = 0; i < bspMem->shared.quake1.numedges; i++) {
  551.       bspMem->shared.quake1.dedges[i].v[0] = LittleShort(bspMem->shared.quake1.dedges[i].v[0]);
  552.       bspMem->shared.quake1.dedges[i].v[1] = LittleShort(bspMem->shared.quake1.dedges[i].v[1]);
  553.     }
  554.  
  555.   /*
  556.    * surfedges
  557.    */
  558.   if (bspMem->availHeaders & LUMP_SURFEDGES)
  559.     for (i = 0; i < bspMem->shared.quake1.numsurfedges; i++)
  560.       bspMem->shared.quake1.dsurfedges[i] = LittleLong(bspMem->shared.quake1.dsurfedges[i]);
  561.  
  562.   /* differencies */
  563.   if (bspMem->bspVersion == BSP_VERSION_Q1) {
  564.     struct dmodel_t *d;
  565.     struct dmiptexlump_t *mtl;
  566.  
  567.     /*
  568.      * miptex
  569.      */
  570.     if (bspMem->availHeaders & LUMP_TEXTURES)
  571.       if (bspMem->shared.quake1.texdatasize) {
  572.     mtl = (struct dmiptexlump_t *)bspMem->shared.quake1.dtexdata;
  573.     if (toDisk)
  574.       c = mtl->nummiptex;
  575.     else
  576.       c = LittleLong(mtl->nummiptex);
  577.     mtl->nummiptex = LittleLong(mtl->nummiptex);
  578.     for (i = 0; i < c; i++)
  579.       mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
  580.       }
  581.  
  582.     /*
  583.      * nodes
  584.      */
  585.     if (bspMem->availHeaders & LUMP_NODES)
  586.       for (i = 0; i < bspMem->shared.quake1.numnodes; i++) {
  587.     bspMem->shared.quake1.dnodes[i].planenum = LittleLong(bspMem->shared.quake1.dnodes[i].planenum);
  588.     for (j = 0; j < 3; j++) {
  589.       bspMem->shared.quake1.dnodes[i].mins[j] = LittleShort(bspMem->shared.quake1.dnodes[i].mins[j]);
  590.       bspMem->shared.quake1.dnodes[i].maxs[j] = LittleShort(bspMem->shared.quake1.dnodes[i].maxs[j]);
  591.     }
  592.     bspMem->shared.quake1.dnodes[i].children[0] = LittleShort(bspMem->shared.quake1.dnodes[i].children[0]);
  593.     bspMem->shared.quake1.dnodes[i].children[1] = LittleShort(bspMem->shared.quake1.dnodes[i].children[1]);
  594.     bspMem->shared.quake1.dnodes[i].firstface = LittleShort(bspMem->shared.quake1.dnodes[i].firstface);
  595.     bspMem->shared.quake1.dnodes[i].numfaces = LittleShort(bspMem->shared.quake1.dnodes[i].numfaces);
  596.       }
  597.  
  598.     /*
  599.      * texinfos
  600.      */
  601.     if (bspMem->availHeaders & LUMP_TEXINFO)
  602.       for (i = 0; i < bspMem->shared.quake1.numtexinfo; i++) {
  603.     for (j = 0; j < 8; j++)
  604.       bspMem->shared.quake1.texinfo[i].vecs[0][j] = LittleFloat(bspMem->shared.quake1.texinfo[i].vecs[0][j]);
  605.     bspMem->shared.quake1.texinfo[i].miptex = LittleLong(bspMem->shared.quake1.texinfo[i].miptex);
  606.     bspMem->shared.quake1.texinfo[i].flags = LittleLong(bspMem->shared.quake1.texinfo[i].flags);
  607.       }
  608.  
  609.     /*
  610.      * clipnodes
  611.      */
  612.     if (bspMem->availHeaders & LUMP_CLIPNODES)
  613.       for (i = 0; i < bspMem->shared.quake1.numclipnodes; i++) {
  614.     bspMem->shared.quake1.dclipnodes[i].planenum = LittleLong(bspMem->shared.quake1.dclipnodes[i].planenum);
  615.     bspMem->shared.quake1.dclipnodes[i].children[0] = LittleShort(bspMem->shared.quake1.dclipnodes[i].children[0]);
  616.     bspMem->shared.quake1.dclipnodes[i].children[1] = LittleShort(bspMem->shared.quake1.dclipnodes[i].children[1]);
  617.       }
  618.  
  619.     /*
  620.      * leafs
  621.      */
  622.     if (bspMem->availHeaders & LUMP_LEAFS)
  623.       for (i = 0; i < bspMem->shared.quake1.numleafs; i++) {
  624.     bspMem->shared.quake1.dleafs[i].contents = LittleLong(bspMem->shared.quake1.dleafs[i].contents);
  625.     for (j = 0; j < 3; j++) {
  626.       bspMem->shared.quake1.dleafs[i].mins[j] = LittleShort(bspMem->shared.quake1.dleafs[i].mins[j]);
  627.       bspMem->shared.quake1.dleafs[i].maxs[j] = LittleShort(bspMem->shared.quake1.dleafs[i].maxs[j]);
  628.     }
  629.     bspMem->shared.quake1.dleafs[i].firstmarksurface = LittleShort(bspMem->shared.quake1.dleafs[i].firstmarksurface);
  630.     bspMem->shared.quake1.dleafs[i].nummarksurfaces = LittleShort(bspMem->shared.quake1.dleafs[i].nummarksurfaces);
  631.     bspMem->shared.quake1.dleafs[i].visofs = LittleLong(bspMem->shared.quake1.dleafs[i].visofs);
  632.       }
  633.  
  634.     /*
  635.      * models
  636.      */
  637.     if (bspMem->availHeaders & LUMP_MODELS) {
  638.       for (i = 0; i < bspMem->shared.quake1.nummodels; i++) {
  639.     d = &bspMem->shared.quake1.dmodels[i];
  640.     for (j = 0; j < MAX_MAP_HULLS; j++)
  641.       d->headnode[j] = LittleLong(d->headnode[j]);
  642.     d->visleafs = LittleLong(d->visleafs);
  643.     d->firstface = LittleLong(d->firstface);
  644.     d->numfaces = LittleLong(d->numfaces);
  645.     for (j = 0; j < 3; j++) {
  646.       d->mins[j] = LittleFloat(d->mins[j]);
  647.       d->maxs[j] = LittleFloat(d->maxs[j]);
  648.       d->origin[j] = LittleFloat(d->origin[j]);
  649.     }
  650.       }
  651.     }
  652.   }
  653.   else if (bspMem->bspVersion == BSP_VERSION_Q2) {
  654.     struct dmodel2_t *d;
  655.  
  656.     /*
  657.      * models
  658.      */
  659.     if (bspMem->availHeaders & LUMP_MODELS)
  660.       for (i = 0; i < bspMem->shared.quake2.nummodels; i++) {
  661.     d = &bspMem->shared.quake2.dmodels[i];
  662.     d->headnode = LittleLong(d->headnode);
  663.     d->firstface = LittleLong(d->firstface);
  664.     d->numfaces = LittleLong(d->numfaces);
  665.     for (j = 0; j < 3; j++) {
  666.       d->mins[j] = LittleFloat(d->mins[j]);
  667.       d->maxs[j] = LittleFloat(d->maxs[j]);
  668.       d->origin[j] = LittleFloat(d->origin[j]);
  669.     }
  670.       }
  671.  
  672.     /*
  673.      * texinfos
  674.      */
  675.     if (bspMem->availHeaders & LUMP_TEXINFO)
  676.       for (i = 0; i < bspMem->shared.quake2.numtexinfo; i++) {
  677.     for (j = 0; j < 8; j++)
  678.       bspMem->shared.quake2.texinfo[i].vecs[0][j] = LittleFloat(bspMem->shared.quake2.texinfo[i].vecs[0][j]);
  679.     bspMem->shared.quake2.texinfo[i].flags = LittleLong(bspMem->shared.quake2.texinfo[i].flags);
  680.     bspMem->shared.quake2.texinfo[i].value = LittleLong(bspMem->shared.quake2.texinfo[i].value);
  681.     bspMem->shared.quake2.texinfo[i].nexttexinfo = LittleLong(bspMem->shared.quake2.texinfo[i].nexttexinfo);
  682.       }
  683.  
  684.     /*
  685.      * nodes
  686.      */
  687.     if (bspMem->availHeaders & LUMP_NODES)
  688.       for (i = 0; i < bspMem->shared.quake2.numnodes; i++) {
  689.     bspMem->shared.quake2.dnodes[i].planenum = LittleLong(bspMem->shared.quake2.dnodes[i].planenum);
  690.     for (j = 0; j < 3; j++) {
  691.       bspMem->shared.quake2.dnodes[i].mins[j] = LittleShort(bspMem->shared.quake2.dnodes[i].mins[j]);
  692.       bspMem->shared.quake2.dnodes[i].maxs[j] = LittleShort(bspMem->shared.quake2.dnodes[i].maxs[j]);
  693.     }
  694.     bspMem->shared.quake2.dnodes[i].children[0] = LittleLong(bspMem->shared.quake2.dnodes[i].children[0]);
  695.     bspMem->shared.quake2.dnodes[i].children[1] = LittleLong(bspMem->shared.quake2.dnodes[i].children[1]);
  696.     bspMem->shared.quake2.dnodes[i].firstface = LittleShort(bspMem->shared.quake2.dnodes[i].firstface);
  697.     bspMem->shared.quake2.dnodes[i].numfaces = LittleShort(bspMem->shared.quake2.dnodes[i].numfaces);
  698.       }
  699.  
  700.     /*
  701.      * leafs
  702.      */
  703.     if (bspMem->availHeaders & LUMP_LEAFS)
  704.       for (i = 0; i < bspMem->shared.quake2.numleafs; i++) {
  705.     bspMem->shared.quake2.dleafs[i].contents = LittleLong(bspMem->shared.quake2.dleafs[i].contents);
  706.     bspMem->shared.quake2.dleafs[i].cluster = LittleLong(bspMem->shared.quake2.dleafs[i].cluster);
  707.     bspMem->shared.quake2.dleafs[i].area = LittleLong(bspMem->shared.quake2.dleafs[i].area);
  708.     for (j = 0; j < 3; j++) {
  709.       bspMem->shared.quake2.dleafs[i].mins[j] = LittleShort(bspMem->shared.quake2.dleafs[i].mins[j]);
  710.       bspMem->shared.quake2.dleafs[i].maxs[j] = LittleShort(bspMem->shared.quake2.dleafs[i].maxs[j]);
  711.     }
  712.     bspMem->shared.quake2.dleafs[i].firstleafface = LittleShort(bspMem->shared.quake2.dleafs[i].firstleafface);
  713.     bspMem->shared.quake2.dleafs[i].numleaffaces = LittleShort(bspMem->shared.quake2.dleafs[i].numleaffaces);
  714.     bspMem->shared.quake2.dleafs[i].firstleafbrush = LittleShort(bspMem->shared.quake2.dleafs[i].firstleafbrush);
  715.     bspMem->shared.quake2.dleafs[i].numleafbrushes = LittleShort(bspMem->shared.quake2.dleafs[i].numleafbrushes);
  716.       }
  717.  
  718.     /*
  719.      * leafbrushes
  720.      */
  721.     if (bspMem->availHeaders & LUMP_LEAFBRUSHES)
  722.       for (i = 0; i < bspMem->shared.quake2.numleafbrushes; i++)
  723.     bspMem->shared.quake2.dleafbrushes[i] = LittleShort(bspMem->shared.quake2.dleafbrushes[i]);
  724.  
  725.     /*
  726.      * brushes
  727.      */
  728.     if (bspMem->availHeaders & LUMP_BRUSHES)
  729.       for (i = 0; i < bspMem->shared.quake2.numbrushes; i++) {
  730.     bspMem->shared.quake2.dbrushes[i].firstside = LittleLong(bspMem->shared.quake2.dbrushes[i].firstside);
  731.     bspMem->shared.quake2.dbrushes[i].numsides = LittleLong(bspMem->shared.quake2.dbrushes[i].numsides);
  732.     bspMem->shared.quake2.dbrushes[i].contents = LittleLong(bspMem->shared.quake2.dbrushes[i].contents);
  733.       }
  734.  
  735.     /*
  736.      * areas
  737.      */
  738.     if (bspMem->availHeaders & LUMP_AREAS)
  739.       for (i = 0; i < bspMem->shared.quake2.numareas; i++) {
  740.     bspMem->shared.quake2.dareas[i].numareaportals = LittleLong(bspMem->shared.quake2.dareas[i].numareaportals);
  741.     bspMem->shared.quake2.dareas[i].firstareaportal = LittleLong(bspMem->shared.quake2.dareas[i].firstareaportal);
  742.       }
  743.  
  744.     /*
  745.      * areasportals
  746.      */
  747.     if (bspMem->availHeaders & LUMP_AREAPORTALS)
  748.       for (i = 0; i < bspMem->shared.quake2.numareaportals; i++) {
  749.     bspMem->shared.quake2.dareaportals[i].portalnum = LittleLong(bspMem->shared.quake2.dareaportals[i].portalnum);
  750.     bspMem->shared.quake2.dareaportals[i].otherarea = LittleLong(bspMem->shared.quake2.dareaportals[i].otherarea);
  751.       }
  752.  
  753.     /*
  754.      * brushsides
  755.      */
  756.     if (bspMem->availHeaders & LUMP_BRUSHSIDES)
  757.       for (i = 0; i < bspMem->shared.quake2.numbrushsides; i++) {
  758.     bspMem->shared.quake2.dbrushsides[i].planenum = LittleShort(bspMem->shared.quake2.dbrushsides[i].planenum);
  759.     bspMem->shared.quake2.dbrushsides[i].texinfo = LittleShort(bspMem->shared.quake2.dbrushsides[i].texinfo);
  760.       }
  761.  
  762.     /*
  763.      * visibility
  764.      */
  765.     if (bspMem->availHeaders & LUMP_VISIBILITY) {
  766.       if (toDisk)
  767.     j = bspMem->shared.quake2.clusters->numclusters;
  768.       else
  769.     j = LittleLong(bspMem->shared.quake2.clusters->numclusters);
  770.  
  771.       bspMem->shared.quake2.numclusters = LittleLong(bspMem->shared.quake2.clusters->numclusters);
  772.       bspMem->shared.quake2.clusters->numclusters = LittleLong(bspMem->shared.quake2.clusters->numclusters);
  773.       for (i = 0; i < j; i++) {
  774.     bspMem->shared.quake2.clusters->bitofs[i][0] = LittleLong(bspMem->shared.quake2.clusters->bitofs[i][0]);
  775.     bspMem->shared.quake2.clusters->bitofs[i][1] = LittleLong(bspMem->shared.quake2.clusters->bitofs[i][1]);
  776.       }
  777.     }
  778.   }
  779. }
  780.  
  781. static int GetBlock(register HANDLE bspFile, register struct dpair *dPair, register void **store, register int partSize)
  782. {
  783.   register int blockSize = LittleLong(dPair->size);
  784.  
  785.   if ((*store = (void *)tmalloc(blockSize))) {
  786.     __lseek(bspFile, LittleLong(dPair->offset), SEEK_SET);
  787.     __read(bspFile, *store, blockSize);
  788.     return (blockSize / partSize);
  789.   }
  790.   else {
  791.     eprintf(failed_memory, blockSize, "bspBlock");
  792.     return 0;
  793.   }
  794. }
  795.  
  796. static void PutBlock(register HANDLE bspFile, register struct dpair *dPair, register void *store, register int blockSize)
  797. {
  798.   if (blockSize) {
  799.     dPair->size = LittleLong(blockSize);
  800.     dPair->offset = LittleLong(__ltell(bspFile));
  801.     __write(bspFile, store, (blockSize + 3) & ~3);
  802.     /*
  803.      * probably we want to use it after this
  804.      * tfree(store);
  805.      */
  806.   }
  807.   else {
  808.     dPair->size = 0;
  809.     dPair->offset = LittleLong(__ltell(bspFile));
  810.   }
  811. }
  812.  
  813. /*
  814.  * =============
  815.  * ConvertBSPFile
  816.  *
  817.  * say me what you want, and you get it. this routine
  818.  * is some of the more important and a manager to transparently
  819.  * hide the internals of the bsp-representation to the disk-io
  820.  * -functions rather than the following modifications to the
  821.  * datas
  822.  * =============
  823.  */
  824. static void ConvertBSP(__memBase)
  825. {
  826.   int successfull = 0, i, j;
  827.  
  828.   oprintf("convertmask: %lx\n", bspMem->availHeaders);
  829.  
  830.   /* Quake1 to Quake2, possible? */
  831.   if (bspMem->bspVersion == BSP_VERSION_Q1) {
  832.     eprintf("converting to quake2 bsps currently not supported\n");
  833.   }
  834.   /* Quake2 to Quake1, possible! */
  835.   else if (bspMem->bspVersion == BSP_VERSION_Q2) {
  836.     /*
  837.      * models
  838.      */
  839.     if (bspMem->availHeaders & LUMP_MODELS) {
  840.       struct dmodel_t *dmodels;
  841.  
  842.       if ((dmodels = (struct dmodel_t *)tmalloc(bspMem->shared.quake2.nummodels * sizeof(struct dmodel_t)))) {
  843.     struct dmodel_t *d = dmodels;
  844.     struct dmodel2_t *d2 = bspMem->shared.quake2.dmodels;
  845.  
  846.     for (i = 0; i < bspMem->shared.quake2.nummodels; i++, d++, d2++) {
  847.       /*d->visleafs = ??? */
  848.       d->headnode[0] = d2->headnode;
  849.       d->firstface = d2->firstface;
  850.       d->numfaces = d2->numfaces;
  851.       for (j = 0; j < 3; j++) {
  852.         d->mins[j] = d2->mins[j];
  853.         d->maxs[j] = d2->maxs[j];
  854.         d->origin[j] = d2->origin[j];
  855.       }
  856.     }
  857.     tfree(bspMem->shared.quake2.dmodels);
  858.     bspMem->shared.quake1.dmodels = dmodels;
  859.     successfull++;
  860.       }
  861.       else
  862.     eprintf(failed_memory, bspMem->shared.quake2.nummodels * sizeof(struct dmodel_t), "new dmodels");
  863.     }
  864.  
  865.     /*
  866.      * nodes
  867.      */
  868.     if (bspMem->availHeaders & LUMP_NODES) {
  869.       struct dnode_t *dnodes;
  870.  
  871.       if ((dnodes = (struct dnode_t *)tmalloc(bspMem->shared.quake2.numnodes * sizeof(struct dnode_t)))) {
  872.     struct dnode_t *d = dnodes;
  873.     struct dnode2_t *d2 = bspMem->shared.quake2.dnodes;
  874.  
  875.     for (i = 0; i < bspMem->shared.quake2.numnodes; i++, d++, d2++) {
  876.       d->planenum = d2->planenum;
  877.       for (j = 0; j < 3; j++) {
  878.         d->mins[j] = d2->mins[j];
  879.         d->maxs[j] = d2->maxs[j];
  880.       }
  881.       if (d2->children[0] > 32767)
  882.         eprintf("node-children overflow\n");
  883.       d->children[0] = (short int)d2->children[0];
  884.       if (d2->children[1] > 32767)
  885.         eprintf("node-children overflow\n");
  886.       d->children[1] = (short int)d2->children[1];
  887.       d->firstface = d2->firstface;
  888.       d->numfaces = d2->numfaces;
  889.     }
  890.     tfree(bspMem->shared.quake2.dnodes);
  891.     bspMem->shared.quake1.dnodes = dnodes;
  892.     successfull++;
  893.       }
  894.       else
  895.     eprintf(failed_memory, bspMem->shared.quake2.numnodes * sizeof(struct dnode_t), "new dnodes");
  896.     }
  897.  
  898.     /*
  899.      * texinfos
  900.      */
  901.     if (bspMem->availHeaders & LUMP_TEXINFO) {
  902.       struct texinfo *dtexinfo;
  903.  
  904.       AllocClusters(bspMem, LUMP_TEXTURES | MAP_TEXSTRINGS);
  905.       if ((dtexinfo = (struct texinfo *)tmalloc(bspMem->shared.quake2.numtexinfo * sizeof(struct texinfo)))) {
  906.     struct texinfo *t = dtexinfo;
  907.     struct texinfo2 *t2 = bspMem->shared.quake2.texinfo;
  908.     char mipName[16 + 1];
  909.  
  910.     for (i = 0; i < bspMem->shared.quake2.numtexinfo; i++, t++, t2++) {
  911.       mipName[0] = '\0';
  912.  
  913.       for (j = 0; j < 8; j++)
  914.         t->vecs[0][j] = t2->vecs[0][j];
  915.       /* ??? = t2->value;                           // light value */
  916.  
  917.       if (t2->flags & SURF_NODRAW) {
  918.         __strcpy(mipName, "clip");
  919.       }
  920.       else {
  921.         if (t2->flags & SURF_SKY) {
  922.           __strcpy(mipName, "sky");
  923.           t->flags = TEX_SPECIAL;
  924.         }
  925.         else if (t2->flags & SURF_WARP) {
  926.           __strcpy(mipName, "*");
  927.           t->flags = TEX_SPECIAL;
  928.         }
  929.         else {
  930.           /* ??? = t2->nexttexinfo;                 // has something to do with animatable textures */
  931.           if (t2->nexttexinfo != -1)
  932.         __strncat(mipName, "+0", 16);            /* animatable, TODO: fix filename of nexttexinfo, we must parse out all animtexs at the beginning */
  933.         }
  934.         __strncat(mipName, GetFile(t2->texture), 16);    /* */
  935.       }
  936.       t->miptex = FindMiptex(bspMem, mipName);        /* register texturename */
  937.     }
  938.     tfree(bspMem->shared.quake2.texinfo);
  939.     bspMem->shared.quake1.texinfo = dtexinfo;
  940.     WriteMiptex(bspMem);                    /* load the textures into memory */
  941.     successfull++;
  942.       }
  943.       else
  944.     eprintf(failed_memory, bspMem->shared.quake2.numtexinfo * sizeof(struct texinfo), "new texinfos");
  945.     }
  946.  
  947.     /*
  948.      * leafs
  949.      */
  950.     if (bspMem->availHeaders & LUMP_LEAFS) {
  951.       struct dleaf_t *dleafs;
  952.  
  953.       if ((dleafs = (struct dleaf_t *)tmalloc(bspMem->shared.quake2.numleafs * sizeof(struct dleaf_t)))) {
  954.     struct dleaf_t *d = dleafs;
  955.     struct dleaf2_t *d2 = bspMem->shared.quake2.dleafs;
  956.  
  957.     for (i = 0; i < bspMem->shared.quake2.numleafs; i++, d++, d2++) {
  958.       if (d2->contents & CONTENTS2_SOLID)
  959.         d->contents = CONTENTS_SOLID;
  960.       else if (d2->contents & CONTENTS2_WATER)
  961.         d->contents = CONTENTS_WATER;
  962.       else if (d2->contents & CONTENTS2_SLIME)
  963.         d->contents = CONTENTS_SLIME;
  964.       else if (d2->contents & CONTENTS2_LAVA)
  965.         d->contents = CONTENTS_LAVA;
  966.       else if (d2->contents & CONTENTS2_AUX)
  967.         d->contents = CONTENTS_SKY;
  968.       else
  969.         d->contents = CONTENTS_EMPTY;
  970.  
  971.       d->visofs = (int)d2->cluster;
  972.       /* ??? = d2->area; */
  973.       for (j = 0; j < 3; j++) {
  974.         d->mins[j] = d2->mins[j];
  975.         d->maxs[j] = d2->maxs[j];
  976.       }
  977.       d->firstmarksurface = d2->firstleafface;
  978.       d->nummarksurfaces = d2->numleaffaces;
  979.       /* ??? = d2->firstleafbrush; */
  980.       /* ??? = d2->numleafbrushes; */
  981.       /* d->ambient_level[...] = ??? */
  982.     }
  983.     tfree(bspMem->shared.quake2.dleafs);
  984.     bspMem->shared.quake1.dleafs = dleafs;
  985.     successfull++;
  986.       }
  987.       else
  988.     eprintf(failed_memory, bspMem->shared.quake2.numleafs * sizeof(struct dleaf_t), "new dleafs");
  989.     }
  990.  
  991.     /*
  992.      * visibility
  993.      */
  994.     if (bspMem->availHeaders & LUMP_VISIBILITY) {
  995.       unsigned char *dvisdata;
  996.  
  997.       if ((dvisdata = (unsigned char *)tmalloc(bspMem->shared.quake2.numclusters * sizeof(int)))) {
  998.     int *d = (int *)dvisdata;
  999.     int *d2 = &bspMem->shared.quake2.clusters->bitofs[0][0];
  1000.     int i;
  1001.  
  1002.     for (i = 0; i < bspMem->shared.quake2.numclusters; i++, d2++)
  1003.       *d++ = *d2++;
  1004.  
  1005.     tfree(bspMem->shared.quake2.clusters);
  1006.     bspMem->shared.quake1.dvisdata = dvisdata;
  1007.     bspMem->shared.quake1.visdatasize = bspMem->shared.quake2.numclusters * (sizeof(int) / sizeof(unsigned char));
  1008.  
  1009.     successfull++;
  1010.       }
  1011.       else
  1012.     eprintf(failed_memory, bspMem->shared.quake2.numclusters * sizeof(int), "new dvisdata");
  1013.     }
  1014.  
  1015.     if (successfull == 5)
  1016.       bspMem->bspVersion = BSP_VERSION_Q1;
  1017.     else
  1018.       Error("destroyed internal bsp-representation while incorrect translation (%d correct)\n", successfull);
  1019.   }
  1020. }
  1021.  
  1022. /*
  1023.  * =============
  1024.  * LoadBSPFile
  1025.  *
  1026.  * this loads a bsp-file to the internal representation
  1027.  * =============
  1028.  */
  1029. struct memory *LoadBSP(HANDLE bspFile, int availLoad, unsigned char versionLoad)
  1030. {
  1031.   __memBase = 0;
  1032.  
  1033.   if ((bspMem = (struct memory *)tmalloc(sizeof(struct memory)))) {
  1034.     union header {
  1035.       struct bspheader Header1;
  1036.       struct bspheader2 Header2;
  1037.     } Header;
  1038.  
  1039.     __bzero(&Header, sizeof(Header));
  1040.     __bzero(bspMem, sizeof(struct memory));
  1041.  
  1042.     oprintf("loadmask: %lx\n", availLoad);
  1043.  
  1044.     /*
  1045.      * load the file header
  1046.      */
  1047.     __lseek(bspFile, 0, SEEK_SET);
  1048.     __read(bspFile, &Header, sizeof(struct bspheader));
  1049.  
  1050.     if (Header.Header1.version == LittleLong(BSP_VERSION_Q1)) {
  1051.       mprintf("read Quake1 binary space partitioning file ...\n");
  1052.       bspMem->bspVersion = BSP_VERSION_Q1;
  1053.       bspMem->availHeaders = availLoad;
  1054.  
  1055.       if (availLoad & LUMP_ENTITIES)
  1056.     bspMem->shared.quake1.entdatasize = bspMem->shared.quake1.max_entdatasize = GetBlock(bspFile, &Header.Header1.entities, (void **)&bspMem->shared.quake1.dentdata, sizeof(char));
  1057.  
  1058.       if (availLoad & LUMP_PLANES)
  1059.     bspMem->shared.quake1.numplanes = bspMem->shared.quake1.max_numplanes = GetBlock(bspFile, &Header.Header1.planes, (void **)&bspMem->shared.quake1.dplanes, sizeof(struct dplane_t));
  1060.  
  1061.       if (availLoad & LUMP_TEXTURES)
  1062.     bspMem->shared.quake1.texdatasize = bspMem->shared.quake1.max_texdatasize = GetBlock(bspFile, &Header.Header1.miptex, (void **)&bspMem->shared.quake1.dtexdata, sizeof(unsigned char));
  1063.  
  1064.       if (availLoad & LUMP_VERTEXES)
  1065.     bspMem->shared.quake1.numvertexes = bspMem->shared.quake1.max_numvertexes = GetBlock(bspFile, &Header.Header1.vertices, (void **)&bspMem->shared.quake1.dvertexes, sizeof(struct dvertex_t));
  1066.  
  1067.       if (availLoad & LUMP_VISIBILITY)
  1068.     bspMem->shared.quake1.visdatasize = bspMem->shared.quake1.max_visdatasize = GetBlock(bspFile, &Header.Header1.visilist, (void **)&bspMem->shared.quake1.dvisdata, sizeof(unsigned char));
  1069.  
  1070.       if (availLoad & LUMP_NODES)
  1071.     bspMem->shared.quake1.numnodes = bspMem->shared.quake1.max_numnodes = GetBlock(bspFile, &Header.Header1.nodes, (void **)&bspMem->shared.quake1.dnodes, sizeof(struct dnode_t));
  1072.  
  1073.       if (availLoad & LUMP_TEXINFO)
  1074.     bspMem->shared.quake1.numtexinfo = bspMem->shared.quake1.max_numtexinfo = GetBlock(bspFile, &Header.Header1.texinfo, (void **)&bspMem->shared.quake1.texinfo, sizeof(struct texinfo));
  1075.  
  1076.       if (availLoad & LUMP_FACES)
  1077.     bspMem->shared.quake1.numfaces = bspMem->shared.quake1.max_numfaces = GetBlock(bspFile, &Header.Header1.faces, (void **)&bspMem->shared.quake1.dfaces, sizeof(struct dface_t));
  1078.  
  1079.       if (availLoad & LUMP_LIGHTING)
  1080.     bspMem->shared.quake1.lightdatasize = bspMem->shared.quake1.max_lightdatasize = GetBlock(bspFile, &Header.Header1.lightmaps, (void **)&bspMem->shared.quake1.dlightdata, sizeof(unsigned char));
  1081.  
  1082.       if (availLoad & LUMP_CLIPNODES)
  1083.     bspMem->shared.quake1.numclipnodes = bspMem->shared.quake1.max_numclipnodes = GetBlock(bspFile, &Header.Header1.clipnodes, (void **)&bspMem->shared.quake1.dclipnodes, sizeof(struct dclipnode_t));
  1084.  
  1085.       if (availLoad & LUMP_LEAFS)
  1086.     bspMem->shared.quake1.numleafs = bspMem->shared.quake1.max_numleafs = GetBlock(bspFile, &Header.Header1.leaves, (void **)&bspMem->shared.quake1.dleafs, sizeof(struct dleaf_t));
  1087.  
  1088.       if (availLoad & LUMP_MARKSURFACES)
  1089.     bspMem->shared.quake1.nummarksurfaces = bspMem->shared.quake1.max_nummarksurfaces = GetBlock(bspFile, &Header.Header1.lface, (void **)&bspMem->shared.quake1.dmarksurfaces, sizeof(unsigned short int));
  1090.  
  1091.       if (availLoad & LUMP_EDGES)
  1092.     bspMem->shared.quake1.numedges = bspMem->shared.quake1.max_numedges = GetBlock(bspFile, &Header.Header1.edges, (void **)&bspMem->shared.quake1.dedges, sizeof(struct dedge_t));
  1093.  
  1094.       if (availLoad & LUMP_SURFEDGES)
  1095.     bspMem->shared.quake1.numsurfedges = bspMem->shared.quake1.max_numsurfedges = GetBlock(bspFile, &Header.Header1.ledges, (void **)&bspMem->shared.quake1.dsurfedges, sizeof(int));
  1096.  
  1097.       if (availLoad & LUMP_MODELS)
  1098.     bspMem->shared.quake1.nummodels = bspMem->shared.quake1.max_nummodels = GetBlock(bspFile, &Header.Header1.models, (void **)&bspMem->shared.quake1.dmodels, sizeof(struct dmodel_t));
  1099.     }
  1100.     else if ((Header.Header2.version == LittleLong(BSP_VERSION_Q2)) && (Header.Header2.identifier == MAGIC_BSP_Q2)) {
  1101.       /* read the outstanding */
  1102.       __read(bspFile, &Header.Header2 + sizeof(struct bspheader), sizeof(struct bspheader2) - sizeof(struct bspheader));
  1103.  
  1104.       mprintf("read Quake2 binary space partitioning file ...\n");
  1105.       bspMem->bspVersion = BSP_VERSION_Q2;
  1106.       bspMem->availHeaders = availLoad;
  1107.  
  1108.       if (availLoad & LUMP_ENTITIES)
  1109.     bspMem->shared.quake2.entdatasize = bspMem->shared.quake2.max_entdatasize = GetBlock(bspFile, &Header.Header2.entities, (void **)&bspMem->shared.quake2.dentdata, sizeof(char));
  1110.  
  1111.       if (availLoad & LUMP_PLANES)
  1112.     bspMem->shared.quake2.numplanes = bspMem->shared.quake2.max_numplanes = GetBlock(bspFile, &Header.Header2.planes, (void **)&bspMem->shared.quake2.dplanes, sizeof(struct dplane_t));
  1113.  
  1114.       if (availLoad & LUMP_VERTEXES)
  1115.     bspMem->shared.quake2.numvertexes = bspMem->shared.quake2.max_numvertexes = GetBlock(bspFile, &Header.Header2.vertices, (void **)&bspMem->shared.quake2.dvertexes, sizeof(struct dvertex_t));
  1116.  
  1117.       if (availLoad & LUMP_VISIBILITY)
  1118.     bspMem->shared.quake2.numclusters = bspMem->shared.quake2.max_numclusters = GetBlock(bspFile, &Header.Header2.visilist, (void **)&bspMem->shared.quake2.clusters, sizeof(unsigned char));
  1119.  
  1120.       if (availLoad & LUMP_NODES)
  1121.     bspMem->shared.quake2.numnodes = bspMem->shared.quake2.max_numnodes = GetBlock(bspFile, &Header.Header2.nodes, (void **)&bspMem->shared.quake2.dnodes, sizeof(struct dnode2_t));
  1122.  
  1123.       if (availLoad & LUMP_TEXINFO)
  1124.     bspMem->shared.quake2.numtexinfo = bspMem->shared.quake2.max_numtexinfo = GetBlock(bspFile, &Header.Header2.texinfo, (void **)&bspMem->shared.quake2.texinfo, sizeof(struct texinfo2));
  1125.  
  1126.       if (availLoad & LUMP_FACES)
  1127.     bspMem->shared.quake2.numfaces = bspMem->shared.quake2.max_numfaces = GetBlock(bspFile, &Header.Header2.faces, (void **)&bspMem->shared.quake2.dfaces, sizeof(struct dface_t));
  1128.  
  1129.       if (availLoad & LUMP_LIGHTING)
  1130.     bspMem->shared.quake2.lightdatasize = bspMem->shared.quake2.max_lightdatasize = GetBlock(bspFile, &Header.Header2.lightmaps, (void **)&bspMem->shared.quake2.dlightdata, sizeof(unsigned char));
  1131.  
  1132.       if (availLoad & LUMP_LEAFS)
  1133.     bspMem->shared.quake2.numleafs = bspMem->shared.quake2.max_numleafs = GetBlock(bspFile, &Header.Header2.leaves, (void **)&bspMem->shared.quake2.dleafs, sizeof(struct dleaf2_t));
  1134.  
  1135.       if (availLoad & LUMP_LEAFFACES)
  1136.     bspMem->shared.quake2.numleaffaces = bspMem->shared.quake2.max_numleaffaces = GetBlock(bspFile, &Header.Header2.lface, (void **)&bspMem->shared.quake2.dleaffaces, sizeof(unsigned short int));
  1137.  
  1138.       if (availLoad & LUMP_EDGES)
  1139.     bspMem->shared.quake2.numedges = bspMem->shared.quake2.max_numedges = GetBlock(bspFile, &Header.Header2.edges, (void **)&bspMem->shared.quake2.dedges, sizeof(struct dedge_t));
  1140.  
  1141.       if (availLoad & LUMP_SURFEDGES)
  1142.     bspMem->shared.quake2.numsurfedges = bspMem->shared.quake2.max_numsurfedges = GetBlock(bspFile, &Header.Header2.ledges, (void **)&bspMem->shared.quake2.dsurfedges, sizeof(int));
  1143.  
  1144.       if (availLoad & LUMP_MODELS)
  1145.     bspMem->shared.quake2.nummodels = bspMem->shared.quake2.max_nummodels = GetBlock(bspFile, &Header.Header2.models, (void **)&bspMem->shared.quake2.dmodels, sizeof(struct dmodel2_t));
  1146.  
  1147.       if (availLoad & LUMP_LEAFBRUSHES)
  1148.     bspMem->shared.quake2.numleafbrushes = bspMem->shared.quake2.max_numleafbrushes = GetBlock(bspFile, &Header.Header2.leafbrushes, (void **)&bspMem->shared.quake2.dleafbrushes, sizeof(unsigned short int));
  1149.  
  1150.       if (availLoad & LUMP_BRUSHES)
  1151.     bspMem->shared.quake2.numbrushes = bspMem->shared.quake2.max_numbrushes = GetBlock(bspFile, &Header.Header2.brushes, (void **)&bspMem->shared.quake2.dbrushes, sizeof(struct dbrush2_t));
  1152.  
  1153.       if (availLoad & LUMP_BRUSHSIDES)
  1154.     bspMem->shared.quake2.numbrushsides = bspMem->shared.quake2.max_numbrushsides = GetBlock(bspFile, &Header.Header2.brushsides, (void **)&bspMem->shared.quake2.dbrushsides, sizeof(struct dbrushside2_t));
  1155.  
  1156.       if (availLoad & LUMP_AREAS)
  1157.     bspMem->shared.quake2.numareas = bspMem->shared.quake2.max_numareas = GetBlock(bspFile, &Header.Header2.areas, (void **)&bspMem->shared.quake2.dareas, sizeof(struct darea2_t));
  1158.  
  1159.       if (availLoad & LUMP_AREAPORTALS)
  1160.     bspMem->shared.quake2.numareaportals = bspMem->shared.quake2.max_numareaportals = GetBlock(bspFile, &Header.Header2.areaportals, (void **)&bspMem->shared.quake2.dareaportals, sizeof(struct dareaportal2_t));
  1161.  
  1162.       if (availLoad & LUMP_POPS)
  1163.     bspMem->shared.quake2.numpops = bspMem->shared.quake2.max_numpops = GetBlock(bspFile, &Header.Header2.pops, (void **)&bspMem->shared.quake2.dpops, sizeof(unsigned char));
  1164.     }
  1165.     else {
  1166.       tfree(bspMem);
  1167.       bspMem = 0;
  1168.       eprintf("no valid bsp-file\n");
  1169.       return 0;
  1170.     }
  1171.  
  1172.     /*
  1173.      * swap everything
  1174.      */
  1175.     SwapBSPFile(bspMem, FALSE);
  1176.  
  1177.     /*
  1178.      * convert to opposite
  1179.      */
  1180.     if (((bspMem->bspVersion == BSP_VERSION_Q1) && (versionLoad == BSP_VERSION_Q2)) ||
  1181.     ((bspMem->bspVersion == BSP_VERSION_Q2) && (versionLoad == BSP_VERSION_Q1)))
  1182.       ConvertBSP(bspMem);
  1183.   }
  1184.  
  1185.   return bspMem;
  1186. }
  1187.  
  1188. /*
  1189.  * =============
  1190.  * WriteBSPFile
  1191.  *
  1192.  * this safes the bsp file out of the internal representation
  1193.  * =============
  1194.  */
  1195. void WriteBSP(HANDLE bspFile, __memBase, unsigned char versionSave)
  1196. {
  1197.   if (bspMem) {
  1198.     /*
  1199.      * convert to opposite
  1200.      */
  1201.     if (((bspMem->bspVersion == BSP_VERSION_Q1) && (versionSave == BSP_VERSION_Q2)) ||
  1202.     ((bspMem->bspVersion == BSP_VERSION_Q2) && (versionSave == BSP_VERSION_Q1)))
  1203.       ConvertBSP(bspMem);
  1204.  
  1205.     /*
  1206.      * swap everything
  1207.      */
  1208.     SwapBSPFile(bspMem, TRUE);
  1209.  
  1210.     if (bspMem->bspVersion == BSP_VERSION_Q1) {
  1211.       struct bspheader Header;
  1212.       __bzero(&Header, sizeof(struct bspheader));
  1213.  
  1214.       Header.version = LittleLong(BSP_VERSION_Q1);
  1215.  
  1216.       /*
  1217.        * save the file header
  1218.        */
  1219.       __lseek(bspFile, 0, SEEK_SET);
  1220.       __write(bspFile, &Header, sizeof(struct bspheader));
  1221.  
  1222.       if (bspMem->availHeaders & LUMP_PLANES)
  1223.     PutBlock(bspFile, &Header.planes, (void *)bspMem->shared.quake1.dplanes, bspMem->shared.quake1.numplanes * sizeof(struct dplane_t));
  1224.  
  1225.       if (bspMem->availHeaders & LUMP_LEAFS)
  1226.     PutBlock(bspFile, &Header.leaves, (void *)bspMem->shared.quake1.dleafs, bspMem->shared.quake1.numleafs * sizeof(struct dleaf_t));
  1227.  
  1228.       if (bspMem->availHeaders & LUMP_VERTEXES)
  1229.     PutBlock(bspFile, &Header.vertices, (void *)bspMem->shared.quake1.dvertexes, bspMem->shared.quake1.numvertexes * sizeof(struct dvertex_t));
  1230.  
  1231.       if (bspMem->availHeaders & LUMP_NODES)
  1232.     PutBlock(bspFile, &Header.nodes, (void *)bspMem->shared.quake1.dnodes, bspMem->shared.quake1.numnodes * sizeof(struct dnode_t));
  1233.  
  1234.       if (bspMem->availHeaders & LUMP_TEXINFO)
  1235.     PutBlock(bspFile, &Header.texinfo, (void *)bspMem->shared.quake1.texinfo, bspMem->shared.quake1.numtexinfo * sizeof(struct texinfo));
  1236.  
  1237.       if (bspMem->availHeaders & LUMP_FACES)
  1238.     PutBlock(bspFile, &Header.faces, (void *)bspMem->shared.quake1.dfaces, bspMem->shared.quake1.numfaces * sizeof(struct dface_t));
  1239.  
  1240.       if (bspMem->availHeaders & LUMP_CLIPNODES)
  1241.     PutBlock(bspFile, &Header.clipnodes, (void *)bspMem->shared.quake1.dclipnodes, bspMem->shared.quake1.numclipnodes * sizeof(struct dclipnode_t));
  1242.  
  1243.       if (bspMem->availHeaders & LUMP_MARKSURFACES)
  1244.     PutBlock(bspFile, &Header.lface, (void *)bspMem->shared.quake1.dmarksurfaces, bspMem->shared.quake1.nummarksurfaces * sizeof(unsigned short int));
  1245.  
  1246.       if (bspMem->availHeaders & LUMP_SURFEDGES)
  1247.     PutBlock(bspFile, &Header.ledges, (void *)bspMem->shared.quake1.dsurfedges, bspMem->shared.quake1.numsurfedges * sizeof(int));
  1248.  
  1249.       if (bspMem->availHeaders & LUMP_EDGES)
  1250.     PutBlock(bspFile, &Header.edges, (void *)bspMem->shared.quake1.dedges, bspMem->shared.quake1.numedges * sizeof(struct dedge_t));
  1251.  
  1252.       if (bspMem->availHeaders & LUMP_MODELS)
  1253.     PutBlock(bspFile, &Header.models, (void *)bspMem->shared.quake1.dmodels, bspMem->shared.quake1.nummodels * sizeof(struct dmodel_t));
  1254.  
  1255.       if (bspMem->availHeaders & LUMP_LIGHTING)
  1256.     PutBlock(bspFile, &Header.lightmaps, (void *)bspMem->shared.quake1.dlightdata, bspMem->shared.quake1.lightdatasize * sizeof(unsigned char));
  1257.  
  1258.       if (bspMem->availHeaders & LUMP_VISIBILITY)
  1259.     PutBlock(bspFile, &Header.visilist, (void *)bspMem->shared.quake1.dvisdata, bspMem->shared.quake1.visdatasize * sizeof(unsigned char));
  1260.  
  1261.       if (bspMem->availHeaders & LUMP_ENTITIES)
  1262.     PutBlock(bspFile, &Header.entities, (void *)bspMem->shared.quake1.dentdata, bspMem->shared.quake1.entdatasize * sizeof(char));
  1263.  
  1264.       if (bspMem->availHeaders & LUMP_TEXTURES)
  1265.     PutBlock(bspFile, &Header.miptex, (void *)bspMem->shared.quake1.dtexdata, bspMem->shared.quake1.texdatasize * sizeof(unsigned char));
  1266.  
  1267.       /*
  1268.        * save the file header
  1269.        */
  1270.       __lseek(bspFile, 0, SEEK_SET);
  1271.       __write(bspFile, &Header, sizeof(struct bspheader));
  1272.  
  1273.       /*
  1274.        * tfree(bspMem); 
  1275.        */
  1276.     }
  1277.     else {
  1278.       struct bspheader2 Header;
  1279.       __bzero(&Header, sizeof(struct bspheader2));
  1280.  
  1281.       Header.identifier = MAGIC_BSP_Q2;
  1282.       Header.version = LittleLong(BSP_VERSION_Q2);
  1283.  
  1284.       /*
  1285.        * save the file header
  1286.        */
  1287.       eprintf("saving of quake2 bsps currently not supported\n");
  1288.     }
  1289.   }
  1290. }
  1291.